package cn.iocoder.yudao.module.mqtt.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 二维码生成工具类
 *
 * 功能：
 * - 使用 UUID 生成设备唯一标识码（16 位）
 * - 将唯一码编码为二维码
 * - 支持返回字节数组（用于接口输出）或 Base64（用于前端预览）
 * - 所有操作在内存中完成，不依赖本地文件存储
 *
 * @version 1.0
 * @author: CY_Guo
 * @date: 2025/7/31 8:44
 */
public class QRCodeUtil {

    /**
     * 将指定数据编码为二维码图片的字节数组（PNG 格式）
     *
     * @param data     要写入二维码的原始数据（支持中文、数字、URL、JSON 等）
     * @param width    图片宽度（建议 200~400）
     * @param height   图片高度
     * @return byte[]  PNG 图片的字节流
     * @throws Exception 生成失败时抛出
     */
    public static byte[] generateQRCodeImage(String data, int width, int height) throws Exception {
        if (data == null || data.trim().isEmpty()) {
            throw new IllegalArgumentException("二维码数据不能为空");
        }

        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 纠错等级
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");                   // 支持中文
        hints.put(EncodeHintType.MARGIN, 1);                                // 边距

        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix matrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", baos);
        return baos.toByteArray();
    }

    /**
     * 生成二维码并返回 Base64 编码（前端可直接显示）
     *
     * @param data     要写入二维码的数据
     * @param width    图片宽度
     * @param height   图片高度
     * @return Base64 编码的 Data URL
     * @throws Exception 生成失败时抛出
     */
    public static String generateQRCodeBase64(String data, int width, int height) throws Exception {
        byte[] imageBytes = generateQRCodeImage(data, width, height);
        return "data:image/png;base64," + java.util.Base64.getEncoder().encodeToString(imageBytes);
    }

    /**
     * 生成 12 位大写唯一标识码（基于 UUID）
     *
     * @return 12 位字符串，如 A1B2C3D4E5F6G7H8
     */
    public static String generate12DigitUUID() {
        return UUID.randomUUID()
                .toString()
                .replace("-", "")
                .substring(0, 12)
                .toUpperCase();
    }

    /**
     * 使用示例
     */
    public static void main(String[] args) {
        try {
            // 1. 生成唯一码
            String uuid = generate12DigitUUID();
            System.out.println("生成的设备唯一码：" + uuid);

            // 2. 生成 Base64 二维码（内存中完成）
            String base64QR = generateQRCodeBase64(uuid, 300, 300);
            System.out.println("Base64 二维码已生成（长度：" + base64QR.length() + "）");

            // 3. 可选：打印前 200 个字符预览
            System.out.println("Base64 预览：" + base64QR.substring(0, 200) + "...");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}